package com.z100h.supplychain.evidence.facade.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import com.jeeplus.common.utils.collection.type.Pair;
import com.jeeplus.core.facade.FacadeException;
import com.jeeplus.core.persistence.Page;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.utils.UserUtils;
import com.z100h.supplychain.common.entity.OperationType;
import com.z100h.supplychain.common.entity.StatAbnormalOperation;
import com.z100h.supplychain.common.service.ErpRepairService;
import com.z100h.supplychain.common.service.ErpStatService;
import com.z100h.supplychain.core.ErpServiceType;
import com.z100h.supplychain.core.EvidenceState;
import com.z100h.supplychain.core.EvidenceType;
import com.z100h.supplychain.core.OuterOrderType;
import com.z100h.supplychain.core.ProductionState;
import com.z100h.supplychain.core.RentType;
import com.z100h.supplychain.core.ResourceLockState;
import com.z100h.supplychain.core.ResourceStockoutLockState;
import com.z100h.supplychain.core.ScEventServiceType;
import com.z100h.supplychain.core.ScEventType;
import com.z100h.supplychain.core.StockoutState;
import com.z100h.supplychain.core.biz.entity.CommonEvidence;
import com.z100h.supplychain.core.biz.entity.RealtimeInventory;
import com.z100h.supplychain.core.biz.service.RealtimeInventoryService;
import com.z100h.supplychain.core.process.AbstractStockoutProcess;
import com.z100h.supplychain.customer.entity.CustomerStockroom;
import com.z100h.supplychain.customer.service.CustomerStockroomService;
import com.z100h.supplychain.evidence.entity.ErpSku;
import com.z100h.supplychain.evidence.entity.ScEvent;
import com.z100h.supplychain.evidence.entity.Stockout;
import com.z100h.supplychain.evidence.entity.StockoutErpResourceVo;
import com.z100h.supplychain.evidence.entity.StockoutSku;
import com.z100h.supplychain.evidence.entity.StockoutSkuVo;
import com.z100h.supplychain.evidence.facade.StockoutFacade;
import com.z100h.supplychain.evidence.service.ScEventService;
import com.z100h.supplychain.evidence.service.StockoutErpResourceService;
import com.z100h.supplychain.evidence.service.StockoutResourceService;
import com.z100h.supplychain.evidence.service.StockoutService;
import com.z100h.supplychain.evidence.service.StockoutSkuService;
import com.z100h.supplychain.order.service.OrderService;
import com.z100h.supplychain.sku.entity.Sku;
import com.z100h.supplychain.sku.service.SkuService;

/**
 * @author madara
 * @Title: StockoutFacadeImpl
 * @ProjectName supplychain
 * @Description: 入库单
 * @date 2019/1/17 17:57
 */
@Service
public class StockoutFacadeImpl extends AbstractStockoutProcess<Stockout> implements StockoutFacade<Stockout> {

	private static final ConcurrentHashMap<String, String> stockroomIdMap = new ConcurrentHashMap<String, String>();

	// TODO
	// private final static String URL = "http://192.168.199.199:8080/lehome";
	// private final static String URL = "http://218.2.197.230:8089/lehome";

	@Autowired
	private SkuService skuService;

	@Autowired
	private StockoutService stockoutService;

	@Autowired
	private StockoutSkuService stockoutSkuService;

	@Autowired
	private StockoutResourceService stockoutResourceService;

	@Autowired
	private RealtimeInventoryService realtimeInventoryService;

	@Autowired
	private OrderService orderService;

	@Autowired
	private CustomerStockroomService customerStockroomService;

	@Autowired
	private StockoutErpResourceService stockoutErpResourceService;

	@Autowired
	private ErpRepairService erpRepairService;

	@Autowired
	private ScEventService scEventService;

	@Autowired
	private ErpStatService erpStatService;

	/** 
	 * 
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#createEvidence(com.z100h.supplychain.core.Evidence, java.util.List, com.z100h.supplychain.core.EvidenceState)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年1月26日 下午3:42:40
	 */
	@Override
	@Transactional(readOnly = false)
	protected String createEvidence(Stockout evidence, List<Pair<Sku, Integer>> skus, EvidenceState evidenceState,
			JSONArray skuList, List<String> orderIds, String stockroomId) {
		EvidenceType evidenceType = null;
		if (("RENTOUT").equals(evidence.getStockoutType())) {
			evidenceType = EvidenceType.RENTOUT;
		}
		if (("SALEOUT").equals(evidence.getStockoutType())) {
			evidenceType = EvidenceType.SALEOUT;
		}
		if (("STOCKOUT").equals(evidence.getStockoutType())) {
			evidenceType = EvidenceType.STOCKOUT;
		}
		if (("REPAIROUT").equals(evidence.getStockoutType())) {
			evidenceType = EvidenceType.REPAIROUT;
		}

		CommonEvidence commonEvidence = new CommonEvidence(evidenceType, evidenceState);
		try {

			// step1 插入大E表
			commonEvidenceService.save(commonEvidence);

			String evidenceId = commonEvidence.getId();

			// step2 插入凭证明细
			evidence.setEvidenceId(evidenceId);
			stockoutService.save(evidence);

			// step3 插入出库单sku明细
			stockoutService.saveStockoutSku(skuList, evidenceId);

			if (CollectionUtils.isNotEmpty(orderIds)) {
				orderService.updateOrderStockoutId(evidenceId, orderIds);
				for (String s : orderIds) {
					stockoutService.insertStockoutOrder(s, evidenceId);
					String rentType = orderService.getRentType(s);
					if (RentType.RENT.getType().equals(rentType)) {
						// 插入p_resource erp资源表
						stockoutErpResourceService.insertOrderErpResource(evidenceId,
								commonEvidence.getCreateBy().getId(), s);
					} else {
						// 插入p_resource_sale erp资源表
						stockoutErpResourceService.insertOrderErpResourceOfSale(evidenceId,
								commonEvidence.getCreateBy().getId(), s);
					}
				}
			}
			if (StringUtils.isNotBlank(stockroomId)) {
				List<String> repairIds = customerStockroomService.findRepairIdsByStockroomId(stockroomId);
				if (CollectionUtils.isNotEmpty(repairIds)) {
					for (String r : repairIds) {
						stockoutService.insertStockoutOrder(r, evidenceId);
						// 插入erp资源表
						stockoutErpResourceService.insertRepairErpResource(evidenceId,
								commonEvidence.getCreateBy().getId(), r);
					}
				}
				customerStockroomService.updateRepairStockoutId(stockroomId, evidenceId);

			}

			stockoutService.updateStockoutState(evidenceId, StockoutState.WAITINGFORQUALITYINSPECTION);

			return evidenceId;
		} catch (Exception e) {
			logger.error("Facade Error StockoutFacadeImpl -> createEvidence   " + e.getMessage());
			throw new FacadeException(e.getMessage());
		}
	}

	/**
	 * 
	 * 创建出库单
	 * 
	 * @param evidence
	 * @param evidenceState
	 * @param stockroomId
	 * @return
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年9月23日 下午3:29:13
	 */
	@Deprecated
	@Transactional(readOnly = false)
	protected String createEvidenceOld(Stockout evidence, EvidenceState evidenceState, JSONArray skuList,
			String stockroomId) {
		EvidenceType evidenceType = null;
		if (("RENTOUT").equals(evidence.getStockoutType())) {
			evidenceType = EvidenceType.RENTOUT;
		}
		if (("STOCKOUT").equals(evidence.getStockoutType())) {
			evidenceType = EvidenceType.STOCKOUT;
		}
		if (("REPAIROUT").equals(evidence.getStockoutType())) {
			evidenceType = EvidenceType.REPAIROUT;
		}

		CommonEvidence commonEvidence = new CommonEvidence(evidenceType, evidenceState);
		try {

			// step1 插入大E表
			commonEvidenceService.save(commonEvidence);

			String evidenceId = commonEvidence.getId();

			// 记录生产单创建时间
			ScEvent scEvent = new ScEvent(evidenceId, ScEventServiceType.EVIDENCE.getType(),
					ScEventType.CREATESTOCKOUT.getType(), UserUtils.getUser().getId());
			scEventService.insert(scEvent);

			// step2 插入凭证明细
			evidence.setEvidenceId(evidenceId);
			CustomerStockroom customerStockroom = customerStockroomService.get(evidence.getCustomerId());
			if (customerStockroom != null) {
				evidence.setCustomerName(customerStockroom.getCustomerName());
				evidence.setCustomerContact(customerStockroom.getContract());
				evidence.setCustomerPhone(customerStockroom.getPhone());
			}
			stockoutService.save(evidence);

			/**
			 * 订单处理流程
			 * 1.找到仓库对应订单e_rent_order刷生产单ID
			 * 2.将erp的serviceId及serviceType插入sc的sc_e_stockout_order
			 * 3.将erp需要出库资源Id插入sc的sc_e_stockout_erp_resource
			 * 
			 */
			List<String> orderIds = orderService.findListByStockroomId(stockroomId);

			if (CollectionUtils.isNotEmpty(orderIds)) {
				// 1.
				orderService.updateOrderStockoutId(evidenceId, orderIds);
				for (String orderId : orderIds) {
					// 2.
					stockoutService.insertStockoutOrder(ErpServiceType.ORDERIN.getType(), orderId, evidenceId);
					// 3.
					String rentType = orderService.getRentType(orderId);
					if (RentType.RENT.getType().equals(rentType)) {
						// 插入p_resource erp资源表
						stockoutErpResourceService.insertOrderErpResource(evidenceId,
								commonEvidence.getCreateBy().getId(), orderId);
					} else {
						// 插入p_resource_sale erp资源表
						stockoutErpResourceService.insertOrderErpResourceOfSale(evidenceId,
								commonEvidence.getCreateBy().getId(), orderId);
					}
				}
			}

			/**
			 * 复壮处理流程
			 * 1.将erp的serviceId及serviceType插入sc的sc_e_stockout_order
			 * 2.将erp需要出库资源Id插入sc的sc_e_stockout_erp_resource
			 * 3.找到仓库对应复壮单刷生产单ID
			
			 * 
			 */
			if (StringUtils.isNotBlank(stockroomId)) {
				List<String> repairIds = customerStockroomService.findRepairIdsByStockroomId(stockroomId);
				if (CollectionUtils.isNotEmpty(repairIds)) {
					for (String repairId : repairIds) {
						stockoutService.insertStockoutOrder(ErpServiceType.REPAIRIN.getType(), repairId, evidenceId);
						// 插入erp资源表
						stockoutErpResourceService.insertRepairErpResource(evidenceId,
								commonEvidence.getCreateBy().getId(), repairId);
					}
				}
				customerStockroomService.updateRepairStockoutId(stockroomId, evidenceId);
			}

			// step3标准出库单插入sku表
			if (evidenceType.equals(EvidenceType.STOCKOUT)) {
				stockoutService.saveStockoutSku(skuList, evidenceId);
			} else {
				stockoutSkuService.saveSku(evidenceId);
			}

			stockoutService.updateStockoutState(evidenceId, StockoutState.WAITINGFORQUALITYINSPECTION);

			return evidenceId;
		} catch (Exception e) {
			logger.error("创建出库单异常！" + e.getMessage());
			throw new FacadeException(e.getMessage());
		}
	}

	@Override
	@Transactional(readOnly = false)
	protected List<String> createEvidence(Stockout evidence, EvidenceState evidenceState, JSONArray skuList,
			String stockroomId) {

		List<String> eids = Lists.newArrayList();
		EvidenceType evidenceType = null;
		if (evidence == null) {
			evidence = new Stockout();
			evidence.setStockoutType("RENTOUT");
		}
		if (("RENTOUT").equals(evidence.getStockoutType())) {
			evidenceType = EvidenceType.RENTOUT;
		}
		if (("STOCKOUT").equals(evidence.getStockoutType())) {
			evidenceType = EvidenceType.STOCKOUT;
		}
		// if (("REPAIROUT").equals(evidence.getStockoutType())) {
		// evidenceType = EvidenceType.REPAIROUT;
		// }

		try {

			List<String> waitingServiceIds = new ArrayList<String>();

			/**
			 * 1.补单
			 */
			List<String> supplementaryOrderIds = orderService.findList(stockroomId, "0");
			if (CollectionUtils.isNotEmpty(supplementaryOrderIds)) {

				waitingServiceIds.addAll(supplementaryOrderIds);

				/**
				 * 1.1.大E、stockout
				 * 
				 */
				Stockout stockout = saveEvidenceAndStockout(stockroomId, EvidenceType.SUPPLEMENTOUT.getType(),
						EvidenceType.SUPPLEMENTOUT, evidenceState);

				/**
				 * 1.2.order、erpres
				 */
				saveOrderStockout(stockout, supplementaryOrderIds);

				/**
				 * 1.3.sku
				 */
				saveSkuStockout(stockout, evidenceType, skuList);

				/**
				 * 1.4.单子状态
				 */
				stockoutService.updateStockoutState(stockout.getEvidenceId(),
						StockoutState.WAITINGFORQUALITYINSPECTION);

				eids.add(stockout.getEvidenceId());

			}

			/**
			 * 2.非补单
			 */
			List<String> orderIds = orderService.findList(stockroomId, "1");
			List<String> repairIds = orderService.findRepairList(stockroomId);

			// Thread.sleep(150000);

			if (CollectionUtils.isNotEmpty(orderIds) || CollectionUtils.isNotEmpty(repairIds)) {

				if (CollectionUtils.isNotEmpty(orderIds)) {
					waitingServiceIds.addAll(orderIds);

				}

				if (CollectionUtils.isNotEmpty(repairIds)) {
					waitingServiceIds.addAll(repairIds);

				}

				if (CollectionUtils.isEmpty(waitingServiceIds)) {
					throw new Exception("该stockroomid无serviceid关联！");

				}

				/**
				 * 2.1.大E、stockout
				 */
				Stockout stockout = saveEvidenceAndStockout(stockroomId, evidence.getStockoutType(), evidenceType,
						evidenceState);

				/**
				 * 2.2.order、erpres
				 */
				saveOrderStockout(stockout, orderIds);
				saveRepairStockout(stockout, repairIds);

				/**
				 * 2.3.sku
				 */
				saveSkuStockout(stockout, evidenceType, skuList);

				/**
				 * 2.4.单子状态
				 */
				stockoutService.updateStockoutState(stockout.getEvidenceId(),
						StockoutState.WAITINGFORQUALITYINSPECTION);

				eids.add(stockout.getEvidenceId());

			}

			if (CollectionUtils.isEmpty(waitingServiceIds)) {
				throw new Exception("该stockroomid无serviceid关联！");
			}

			return eids;
		} catch (Exception e) {
			logger.error("创建出库单异常！" + e.getMessage());
			throw new FacadeException(e.getMessage());
		}
	}

	/**
	 * 
	 * 保存大E、stockout
	 * 
	 * @param stockroomId
	 * @param stockoutType
	 * @param evidenceType
	 * @param evidenceState
	 * @return
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2021年5月18日 上午1:14:34
	 */
	private Stockout saveEvidenceAndStockout(String stockroomId, String stockoutType, EvidenceType evidenceType,
			EvidenceState evidenceState) {
		/**
		 * 1.创建大E
		 */
		CommonEvidence commonEvidence = new CommonEvidence(evidenceType, evidenceState);
		commonEvidenceService.save(commonEvidence);
		String evidenceId = commonEvidence.getId();
		/**
		 * 记录生产单创建时间
		 */
		ScEvent scEvent = new ScEvent(evidenceId, ScEventServiceType.EVIDENCE.getType(),
				ScEventType.CREATESTOCKOUT.getType(), UserUtils.getUser().getId());
		scEventService.insert(scEvent);

		/**
		 * 2.创建stockout
		 */
		CustomerStockroom customerStockroom = customerStockroomService.findByStockroomId(stockroomId);
		if (customerStockroom == null) {
			throw new FacadeException("仓库为删除状态，不允许拉单，请联系上报人并拒绝");
		}
		Stockout stockout = new Stockout(evidenceId, stockoutType, stockroomId, customerStockroom.getCustomerId(),
				customerStockroom.getCustomerName(), customerStockroom.getContract(), customerStockroom.getPhone());
		if (StringUtils.equals(evidenceType.getType(), EvidenceType.SUPPLEMENTOUT.getType())) {
			stockout.setIsSupplement("0");
		}
		stockoutService.save(stockout);
		return stockout;
	}

	/**
	 * 
	 * 订单转生产单
	 * 
	 * @param stockout
	 * @param serviceIds
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2021年5月18日 上午12:54:54
	 */
	private void saveOrderStockout(Stockout stockout, List<String> serviceIds) {
		if (CollectionUtils.isNotEmpty(serviceIds)) {

			// 1.反刷Eid
			orderService.updateOrderStockoutId(stockout.getEvidenceId(), serviceIds);
			for (String orderId : serviceIds) {
				// 2.插sc_e_stockout_order
				stockoutService.insertStockoutOrder(ErpServiceType.ORDERIN.getType(), orderId,
						stockout.getEvidenceId());
				// 3.插sc_e_stockout_erp_resource
				String rentType = orderService.getRentType(orderId);
				if (RentType.RENT.getType().equals(rentType)) {
					// 插入p_resource erp资源表
					stockoutErpResourceService.insertOrderErpResource(stockout.getEvidenceId(),
							stockout.getCreateBy().getId(), orderId);
				} else {
					// 插入p_resource_sale erp资源表
					stockoutErpResourceService.insertOrderErpResourceOfSale(stockout.getEvidenceId(),
							stockout.getCreateBy().getId(), orderId);
				}
			}
		}
	}

	/**
	 * 
	 * 复壮单转生产单
	 * 
	 * @param stockout
	 * @param serviceIds
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2021年5月18日 上午12:55:11
	 */
	private void saveRepairStockout(Stockout stockout, List<String> serviceIds) {

		if (CollectionUtils.isNotEmpty(serviceIds)) {
			// s层错误,参数顺序，入参
			// 1.反刷Eid
			orderService.updateRepairStockoutId(stockout.getEvidenceId(), serviceIds);

			for (String repairId : serviceIds) {
				// 2.插sc_e_stockout_order
				stockoutService.insertStockoutOrder(ErpServiceType.REPAIRIN.getType(), repairId,
						stockout.getEvidenceId());
				// 3.插sc_e_stockout_erp_resource
				stockoutErpResourceService.insertRepairErpResource(stockout.getEvidenceId(),
						stockout.getCreateBy().getId(), repairId);
			}
		}

	}

	/**
	 * 
	 * 保存出库sku
	 * sc_e_stockout_sku
	 * 
	 * @param stockout
	 * @param evidenceType
	 * @param skuList
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2021年5月18日 上午12:55:28
	 */
	private void saveSkuStockout(Stockout stockout, EvidenceType evidenceType, JSONArray skuList) {

		// step3标准出库单插入sku表
		if (evidenceType.equals(EvidenceType.STOCKOUT)) {
			stockoutService.saveStockoutSku(skuList, stockout.getEvidenceId());
		} else {
			stockoutSkuService.saveSku(stockout.getEvidenceId());
		}

	}

	/**
	 * 
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#changeResourceWithEvidence(com.z100h.supplychain.core.Evidence, java.util.List)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年4月9日 下午4:16:23
	 */
	@Override
	@Transactional(readOnly = false)
	protected void changeResourceWithEvidence(Stockout evidence, List<String> resourceIds) {
		resourceService.updateResourceToWarehouseId(resourceIds, evidence.getWarehouseId());
	}

	/**
	 * 检查出库资源是否超标
	 *
	 * @param evidenceId
	 * @param resourceIds
	 * @return
	 */
	@Override
	protected List<Pair<Sku, Integer>> checkConfirmResource(String evidenceId, List<String> resourceIds) {

		// step1 先找到出库单sku 明细表 需要扣除res表的数量
		StockoutSku stockoutSku = new StockoutSku();
		stockoutSku.setEvidenceId(evidenceId);
		List<StockoutSku> stockoutSkuList = stockoutSkuService.findList(stockoutSku);// 这里是聚合数据

		// step2 找出资源id 对应sku 聚合
		stockoutSku.setResourceIds(resourceIds);
		List<StockoutSku> stockoutSkus = stockoutSkuService.findResourceIdGroupBySkuId(stockoutSku);

		// step3 循环判断 资源id对应的 sku是否超过 返回超过的资源id
		return this.comparison(stockoutSkus, stockoutSkuList);
	}

	/**
	 * 
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#stockoutLockResource(java.util.List, com.z100h.supplychain.core.ResourceStockoutLockState)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年4月9日 下午4:16:37
	 */
	@Override
	protected Boolean stockoutLockResource(List<String> resourceIds,
			ResourceStockoutLockState resourceStockoutLockState) {
		try {
			resourceService.updateStockoutState(resourceIds, ResourceStockoutLockState.LOCK.getValue());
			return Boolean.TRUE;
		} catch (Exception e) {
			logger.error("Facade Error StockoutFacadeImpl -> createEvidence   " + e.getMessage());
			return Boolean.FALSE;
		}
	}

	/**
	 * 获取单子未结束SKU及数量
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#checkEvidenceFinish(java.lang.String)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年4月9日 下午4:16:55
	 */
	@Override
	protected List<Pair<Sku, Integer>> checkEvidenceFinish(String evidenceId) {
		List<Pair<Sku, Integer>> pairList = new ArrayList<>();
		StockoutSku stockoutSku = new StockoutSku();
		stockoutSku.setEvidenceId(evidenceId);
		List<StockoutSku> stockoutSkuList = stockoutSkuService.findList(stockoutSku);
		for (StockoutSku sto : stockoutSkuList) {
			if (sto.getAmount() > sto.getAmountOut() || sto.getAmount() != sto.getAmountOut()) {
				Pair<Sku, Integer> pair = new Pair<Sku, Integer>(skuService.get(sto.getSkuId().toString()),
						sto.getAmount() - sto.getAmountOut());
				pairList.add(pair);
			}
		}
		return pairList;
	}

	/**
	 * 已经确认的转存
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#saveConfirmedResource(java.util.List, java.lang.String)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年4月9日 下午4:17:04
	 */
	@Override
	@Transactional(readOnly = false)
	protected void saveConfirmedResource(List<String> resourceIds, String evidenceId) {
		try {
			// step1 刷新出库单sku

			// 聚合sku数量
			StockoutSku stockoutSku = new StockoutSku();
			stockoutSku.setResourceIds(resourceIds);
			List<StockoutSku> stockoutSkuList = stockoutSkuService.findResourceIdGroupBySkuId(stockoutSku);
			// 获取sku集合
			Map<Integer, Integer> skocMap = this.getSkuAmountOutMap(stockoutSkuList);

			// 找出单子下 所有sku总数量和已入数量
			stockoutSku.setEvidenceId(evidenceId);
			List<StockoutSku> skuNumList = stockoutSkuService.findList(stockoutSku);
			for (StockoutSku sku : skuNumList) {
				Integer amountIn = skocMap.get(sku.getSkuId());
				if (null != amountIn) {
					sku.setAmountOut(sku.getAmountOut() + amountIn);// 累加已出库数量
					stockoutSkuService.save(sku);// 修改数据库
				}
			}

			// step2 如果是售卖类型 插入出库
			CommonEvidence commonEvidence = commonEvidenceService.get(evidenceId);

			if (commonEvidence.getEvidenceType().equals(EvidenceType.SALEOUT)) {
				stockoutResourceService.addStockoutResource(evidenceId);
			}
		} catch (Exception e) {
			logger.error("Facade Error StockoutFacadeImpl -> saveConfirmedResource   " + e.getMessage());
			throw new FacadeException(e.getMessage());
		}
	}

	/**
	 * 
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#od(java.lang.String, com.z100h.supplychain.core.OuterOrderType)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年4月9日 下午4:17:11
	 */
	@Override
	protected List<Pair<Sku, Integer>> od(String orderId, OuterOrderType orderType) {
		return null;
	}

	/**
	 * 
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#ckeckRealtimeInventory(java.util.List, java.lang.Integer)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年4月9日 下午4:17:19
	 */
	@Override
	protected List<Pair<Sku, Integer>> ckeckRealtimeInventory(List<Pair<Sku, Integer>> skus, Integer moreAmount) {
		User user = UserUtils.getUser();
		List<RealtimeInventory> skuList = realtimeInventoryService.getRealtimeInventory(skus, user.getCompanyId());
		List<Pair<Sku, Integer>> errList = new ArrayList<Pair<Sku, Integer>>();
		List<String> ids = new ArrayList<String>();
		Pair<Sku, Integer> sku = null;
		if (CollectionUtils.isNotEmpty(skus)) {
			// 如果实时库存为空，skus全部库存不够
			if (CollectionUtils.isEmpty(skuList)) {
				errList.addAll(skus);
			} else {
				for (RealtimeInventory r : skuList) {
					ids.add(r.getSkuId());
				}
				for (Pair<Sku, Integer> p : skus) {
					if (!ids.contains(p.getFirst().getId())) {
						errList.add(p);
						break;
					}
					for (RealtimeInventory r : skuList) {
						if (p.getFirst().getId().equals(r.getSkuId())) {
							if (p.getSecond() > r.getAmount() + moreAmount) {
								sku = new Pair<Sku, Integer>(p.getFirst(), p.getSecond() - r.getAmount() - moreAmount);
								errList.add(sku);
							}
							break;
						}
					}
				}
			}
		}
		return errList;
	}

	/**
	 * 手工出库单
	 * 保存
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#save(java.lang.Object)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年4月9日 下午4:12:22
	 */
	@Override
	@Transactional(readOnly = false)
	public List<String> save(Stockout stockout, JSONArray skuList, List<String> orderIds, String stockroomId) {
		try {
			return this.createProcess(stockout, skuList, orderIds, stockroomId);

		} catch (Exception e) {
			logger.error("Facade Error StockoutFacadeImpl -> save   " + e.getMessage());
			throw new FacadeException(e.getMessage());
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#save(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2021年5月17日 下午6:57:23
	 */
	@Override
	@Transactional(readOnly = false)
	public List<String> save(String stockroomId) {
		try {

			if (stockroomIdMap.containsKey(stockroomId)) {

				throw new FacadeException("采购拉单stockroomId重复调动！");

			} else {
				stockroomIdMap.put(stockroomId, stockroomId);
				return this.createProcess(null, null, null, null, stockroomId);
			}

		} catch (Exception e) {
			logger.error("Facade Error StockoutFacadeImpl -> save   " + e.getMessage());
			throw new FacadeException(e.getMessage());
		} finally {
			stockroomIdMap.remove(stockroomId);
		}
	}

	/**
	 * 出库单过机，并且检查出库单是否完成
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#passingMachine(java.lang.Object)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年4月9日 下午4:14:05
	 */
	@Override
	@Transactional(readOnly = false)
	public Map<String, Object> passingMachine(Stockout stockout) {
		Map<String, Object> map = new HashMap<>();
		try {
			List<Pair<Sku, Integer>> pairList = this.confirmProcess(stockout.getResourceIds(), stockout);
			if (CollectionUtils.isEmpty(pairList)) {
				this.finishProcess(stockout.getEvidenceId());
			} else {
				throw new FacadeException("出库资源异常");
			}

		} catch (Exception e) {
			logger.error("Facade Error StockoutFacadeImpl -> passingMachine   " + e.getMessage());
			throw new FacadeException(e.getMessage());
		}
		return map;
	}

	@Override
	public Page<Stockout> findStockoutByPage(Page<Stockout> page, Stockout stockout) {
		return stockoutService.findPage(page, stockout);
	}

	@Override
	public Stockout getStockout(Stockout stockout) {
		return stockoutService.get(stockout.getEvidenceId());
	}

	@Override
	public List<StockoutSku> findStockoutSkuList(StockoutSku stockoutSku) {
		return stockoutSkuService.findList(stockoutSku);
	}

	/**
	 * 比对页面扫描和历史入库的数量是否超库存总数
	 *
	 * @param realitySkuList
	 * @param historySkuList
	 * @return
	 */
	private List<Pair<Sku, Integer>> comparison(List<StockoutSku> realitySkuList, List<StockoutSku> historySkuList) {
		List<Pair<Sku, Integer>> pairList = new ArrayList<>();
		Pair<Sku, Integer> pair;

		// 拿到转换的map
		Map<Integer, Integer> skuAmountOutMap = this.getSkuAmountOutMap(historySkuList);

		Map<Integer, Integer> skuAmountMap = this.getSkuAmountMap(historySkuList);

		// 循环前台传入的list
		for (StockoutSku stockoutSku : realitySkuList) {
			// 拿到sku剩余数量在sql中已处理 amount==null 该sku没有过机
			Integer amountOut = null == skuAmountOutMap.get(stockoutSku.getSkuId()) ? 0
					: skuAmountOutMap.get(stockoutSku.getSkuId());
			// 过闸机数量必须小于等于
			Integer amount = null == skuAmountMap.get(stockoutSku.getSkuId()) ? 0
					: skuAmountMap.get(stockoutSku.getSkuId());

			if (amount == 0 && amountOut == 0) { // 两个都等于0 说明有sku不在当前出库单里面
				pair = new Pair<Sku, Integer>(skuService.get(stockoutSku.getSkuId() + ""), 0);
				pairList.add(pair);
				continue;
			}

			if (amountOut == 0) {// 该sku没有出过库
				if (stockoutSku.getAmount() > amount) {
					pair = new Pair<Sku, Integer>(skuService.get(stockoutSku.getSkuId() + ""),
							stockoutSku.getAmount() - amount);
					pairList.add(pair);
				}
			} else {
				if (stockoutSku.getAmount() > (amount - amountOut)) {
					pair = new Pair<Sku, Integer>(skuService.get(stockoutSku.getSkuId() + ""),
							stockoutSku.getAmount() - amountOut);
					pairList.add(pair);
				}
			}

		}

		if (CollectionUtils.isEmpty(pairList)) {
			return null;
		} else {
			return pairList;
		}
	}

	/**
	 * java8 list转map
	 *
	 * @param historySkuList
	 * @return
	 */
	public Map<Integer, Integer> getSkuAmountOutMap(List<StockoutSku> historySkuList) {
		return historySkuList.stream().collect(Collectors.toMap(StockoutSku::getSkuId, StockoutSku::getAmountOut));
	}

	/**
	 * java8 list转map
	 *
	 * @param historySkuList
	 * @return
	 */
	public Map<Integer, Integer> getSkuAmountMap(List<StockoutSku> historySkuList) {
		return historySkuList.stream().collect(Collectors.toMap(StockoutSku::getSkuId, StockoutSku::getAmount));
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#get(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年4月10日 下午3:20:45
	 */
	@Override
	public Stockout get(String id) {
		return stockoutService.get(id);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findStockoutSkuByEvidenceId(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年4月10日 下午3:20:45
	 */
	@Override
	public List<StockoutSku> findStockoutSkuByEvidenceId(String evidenceId) {
		return stockoutSkuService.findStockoutSkuByEvidenceId(evidenceId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findStockoutSkuByOrderIds(java.util.List)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年4月15日 下午5:28:37
	 */
	@Override
	public List<StockoutSku> findStockoutSkuByOrderIds(List<String> orderIds) {
		return stockoutSkuService.findStockoutSkuByOrderIds(orderIds);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findStockoutSkuByStockroomId(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年4月22日 下午3:26:27
	 */
	@Override
	public List<StockoutSku> findStockoutSkuByStockroomId(String stockroomId) {
		return stockoutSkuService.findStockoutSkuByStockroomId(stockroomId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#quicklyComfirmResource(com.z100h.supplychain.evidence.entity.StockoutSku, java.lang.String, com.z100h.supplychain.core.ResourceStockoutLockState)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年5月14日 下午5:59:38
	 */
	@Override
	@Transactional(readOnly = false)
	protected void quicklyComfirmResource(StockoutSku stockoutSku, String companyId,
			ResourceStockoutLockState toResourceStockoutLockState) {
		// sku顺序出库
		resourceService.updateResourceStockout(stockoutSku.getSkuId(), toResourceStockoutLockState.getValue(),
				stockoutSku.getEvidenceId(), stockoutSku.getAmount(), companyId);

		// stockout_sku表刷amount_sku
		stockoutSkuService.updateStockoutSkuAmountOut(stockoutSku.getEvidenceId(), stockoutSku.getSkuId(),
				stockoutSku.getAmount());
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#quicklyComfirmResourceToErpSku(com.z100h.supplychain.evidence.entity.ErpSku, java.lang.String, com.z100h.supplychain.core.ResourceStockoutLockState)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年9月11日 下午1:53:31
	 */
	@Override
	@Transactional(readOnly = false)
	protected void quicklyComfirmResourceToErpSku(ErpSku erpSku, String companyId,
			ResourceStockoutLockState toResourceStockoutLockState) {
		// sku顺序出库
		resourceService.updateResourceStockoutToErp(erpSku.getErpResId(), erpSku.getSkuId(),
				toResourceStockoutLockState.getValue(), erpSku.getEvidenceId(), erpSku.getAmount(), companyId);

		// stockout_sku表刷amount_sku 增量累加
		stockoutSkuService.updateStockoutSkuAmountIncrementOut(erpSku.getEvidenceId(), erpSku.getSkuId(),
				erpSku.getAmount());
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#ckeckRealtimeInventoryBySku(com.z100h.supplychain.evidence.entity.StockoutSku, java.lang.String)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年5月14日 下午5:59:38
	 */
	@Override
	protected boolean ckeckRealtimeInventoryBySku(StockoutSku stockoutSku, String companyId) {
		Integer usableAmount = resourceService.getUsableResourceBySkuId(stockoutSku.getSkuId(), companyId);
		if (stockoutSku.getAmount() <= usableAmount) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.core.process.AbstractStockoutProcess#ckeckRealtimeInventoryByErpSku(com.z100h.supplychain.evidence.entity.ErpSku, java.lang.String)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年9月11日 上午11:14:04
	 */
	@Override
	protected boolean ckeckRealtimeInventoryByErpSku(ErpSku erpSku, String companyId) {
		Integer usableAmount = resourceService.getUsableResourceBySkuId(erpSku.getSkuId(), companyId);
		if (erpSku.getAmount() <= usableAmount) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#test()
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年5月15日 上午11:41:37
	 */
	@Override
	@Transactional(readOnly = false)
	public void stockoutUnfinishEvidence() {
		this.confirmFinishProcess();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#completeProduction(java.lang.String)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年9月9日 下午2:39:25
	 */
	@Override
	@Transactional(readOnly = false)
	public void completeProduction(String evidenceId) {
		stockoutErpResourceService.productionCompletionByEvidenceId(evidenceId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#completeProduction(java.util.List)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @date: Created on 2019年9月9日 下午2:39:25
	 */
	@Override
	@Transactional(readOnly = false)
	public void completeProduction(List<String> ids) {
		stockoutErpResourceService.productionCompletionByIds(ids);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#qualityControl(java.lang.String)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @throws Throwable 
	 * @date: Created on 2019年9月9日 下午2:46:24
	 */
	@Override
	@Transactional(readOnly = false)
	public void qualityControl(String evidenceId, ProductionState productionState) throws Throwable {
		/**
		 * 2.质检通过的话  刷stockout-sku.out amount 怼上SC资源id
		* 1.stockout-erp表刷状态
		
		 * 3.整个e质检结束以后，e从未完成-已完成
		 */

		if (productionState.equals(ProductionState.QCPASS)) {
			/**
			 * 1.通过 
			
			 */
			this.qcConfirmFinishProcess(evidenceId);

			// 记录质检合格动作
			ScEvent scEvent = new ScEvent(evidenceId, ScEventServiceType.EVIDENCE.getType(),
					ScEventType.QCSTOCKOUTSUCCESS.getType(), UserUtils.getUser().getId());
			scEventService.insert(scEvent);

		} else {// 待整改
			// stockoutErpResourceService.qcFailedByEvidenceId(evidenceId);

			stockoutService.updateStockoutState(evidenceId, StockoutState.WAITINGFORRECTIFICATION);

			// 记录质检不合格动作
			ScEvent scEvent = new ScEvent(evidenceId, ScEventServiceType.EVIDENCE.getType(),
					ScEventType.QCSTOCKOUTFAILURE.getType(), UserUtils.getUser().getId());
			scEventService.insert(scEvent);

		}

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#qualityControl(java.util.List)
	 * @author: Elvin Zhao - 279152260@qq.com 
	 * @throws Throwable 
	 * @date: Created on 2019年9月9日 下午2:46:24
	 */
	@Override
	@Transactional(readOnly = false)
	public void qualityControl(String evidenceId, List<String> ids, ProductionState productionState) throws Throwable {
		if (productionState.equals(ProductionState.QCPASS)) {
			/**
			 * 1.通过
			 * qcConfirmFinishProcess
			 */
			this.qcConfirmFinishProcess(ids, evidenceId);

		} else {
			stockoutErpResourceService.qcFailedByIds(evidenceId, ids);
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findSkuNotStockout()
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月9日 下午3:37:55
	 */
	@Override
	public List<StockoutSkuVo> findSkuNotStockout(String companyId) {
		return stockoutSkuService.findSkuNotStockout(companyId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findStockoutErpResourceVoListByEvidenceId(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月9日 下午4:25:43
	 */
	@Override
	public List<StockoutErpResourceVo> findStockoutErpResourceVoListByEvidenceId(String evidenceId, String state) {
		return stockoutErpResourceService.findStockoutErpResourceVoListByEvidenceId(evidenceId, state);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findQcByPage(com.jeeplus.core.persistence.Page, java.lang.Object)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月10日 下午3:23:25
	 */
	@Override
	public Page<Stockout> findQcByPage(Page<Stockout> page, Stockout stockout) {
		return stockoutService.findQcByPage(page, stockout);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findQcErpResourceVoListByEvidenceId(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月10日 下午3:41:22
	 */
	@Override
	public List<StockoutErpResourceVo> findQcErpResourceVoListByEvidenceId(String evidenceId) {
		return stockoutErpResourceService.findQcErpResourceVoListByEvidenceId(evidenceId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findOutByPage(com.jeeplus.core.persistence.Page, java.lang.Object)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月11日 上午10:22:24
	 */
	@Override
	public Page<Stockout> findOutByPage(Page<Stockout> page, Stockout stockout) {
		return stockoutService.findOutByPage(page, stockout);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findOutErpResourceVoListByEvidenceId(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月11日 上午10:43:09
	 */
	@Override
	public List<StockoutErpResourceVo> findOutErpResourceVoListByEvidenceId(String evidenceId) {
		return stockoutErpResourceService.findOutErpResourceVoListByEvidenceId(evidenceId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findStockoutSkuErpResByIds(java.util.List)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月11日 下午2:51:27
	 */
	@Override
	public List<StockoutSku> findStockoutSkuErpResByIds(List<String> ids) {
		return stockoutErpResourceService.findStockoutSkuErpResByIds(ids);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#outRes(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月16日 下午3:25:05
	 */
	@Override
	@Transactional(readOnly = false)
	public void outRes(String evidenceId) {
		try {
			stockoutErpResourceService.updateOutState(evidenceId);
			finishStockout(evidenceId);
			stockoutService.updateStockoutState(evidenceId, StockoutState.FINISH);

			// 记录出库动作
			ScEvent scEvent = new ScEvent(evidenceId, ScEventServiceType.EVIDENCE.getType(),
					ScEventType.OUTSTOCKOUT.getType(), UserUtils.getUser().getId());
			scEventService.insert(scEvent);

			// /**
			// * 需要刷新订单复壮采购金额的异常复壮id
			// */
			// List<String> errorOrderServiceIds = stockoutService.findMonthErrorStockoutOrderByEid(evidenceId);
			// if (CollectionUtils.isNotEmpty(errorOrderServiceIds)) {
			// System.out.println("$$$$$$$$$$$$orderIds:" + errorOrderServiceIds.toString());
			// orderService.updateOrderPurchasePrice(errorOrderServiceIds);
			// }
			//
			// /**
			// * 需要刷新复壮采购金额的异常复壮id
			// */
			// List<String> errorRepairServiceIds = stockoutService.findMonthErrorStockoutRepairByEid(evidenceId);
			// if (CollectionUtils.isNotEmpty(errorRepairServiceIds)) {
			// System.out.println("$$$$$$$$$$$$repairIds:" + errorRepairServiceIds.toString());
			// orderService.updateRepairPurchasePrice(errorRepairServiceIds);
			// }

		} catch (Exception e) {
			throw new FacadeException("生产单：生产单出库异常！" + e.getMessage());
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#outRes(java.util.List)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月16日 下午3:25:05
	 */
	@Override
	@Transactional(readOnly = false)
	public void outRes(String evidenceId, List<String> ids) {
		stockoutErpResourceService.updateOutStateByIds(ids);
		finishStockout(evidenceId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#finishStockout(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月17日 上午11:11:20
	 */
	@Override
	public void finishStockout(String evidenceId) {
		List<String> ids = stockoutErpResourceService.findResNotOut(evidenceId);
		if (CollectionUtils.isEmpty(ids)) {
			commonEvidenceService.finishEvidence(evidenceId, EvidenceState.FINISH);
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#finishRepair(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月20日 上午11:13:04
	 */
	// @Override
	// public void finishRepair(List<String> repairIds) throws Throwable {
	// final String contentType = "application/json";
	// final String url = URL + "/sc/repair/finish";
	// JSONObject req = new JSONObject();
	// req.put("ids", repairIds);
	// req.put("scMark", "sc:" + UserUtils.getUser().getNo());
	// // String resp = HttpUtils.post(url, req.toJSONString(), false, contentType);
	// HttpUtils.post(url, req.toJSONString(), false, contentType);
	// }

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findNeedProduceByPage(com.jeeplus.core.persistence.Page, com.z100h.supplychain.customer.entity.CustomerStockroom)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月23日 上午10:48:01
	 */
	@Override
	public Page<CustomerStockroom> findNeedProduceByPage(Page<CustomerStockroom> page,
			CustomerStockroom customerStockroom) {
		return customerStockroomService.findNeedProduceByPage(page, customerStockroom);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#cancelRepair(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年9月24日 上午11:33:19
	 */
	@Override
	@Transactional(readOnly = false)
	public void cancelRepair(String stockroomId) {
		try {
			// 删除复壮拆解
			stockoutService.deleteRdOfSpecConsist(stockroomId);
			stockoutService.deleteRdOfSpec(stockroomId);

			// 还原调换资源
			erpRepairService.restoreRepairResourceByStockroomId(stockroomId);

			// 修改运营审核状态
			stockoutService.updateRepairOpState(stockroomId);

			// 插入复壮撤销异常记录
			CustomerStockroom customerStockroom = customerStockroomService.getProjectIdByStockroomId(stockroomId);
			StatAbnormalOperation operation = new StatAbnormalOperation(OperationType.ABNORMAL_3.getType(),
					customerStockroom.getCompanyId(), customerStockroom.getProjectId(), 1);
			erpStatService.insertRejectRepair(operation);

		} catch (Exception e) {
			throw new FacadeException("复壮驳回异常！" + e.getMessage());
		}

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#outCommonStockout(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2019年10月16日 下午6:16:27
	 */
	@Override
	@Transactional(readOnly = false)
	public void outCommonStockout(String evidenceId) {
		this.outCommonStockoutProcess(evidenceId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#getCustomerIdByStockroomId(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2020年4月24日 下午2:31:38
	 */
	@Override
	public String getCustomerIdByStockroomId(String stockroomId) {
		return customerStockroomService.getCustomerIdByStockroomId(stockroomId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#autoQc()
	 * @author: Fyh - 1009173473@qq.com 
	 * @throws Throwable 
	 * @date: Created on 2020年12月23日 下午3:03:04
	 */
	@Override
	public void autoQc() throws Throwable {

		String companyId = "a35ebfd46ddf4bf68415d04f763e634a";
		/**
		 * 所有未出库完成的erpResId
		 */
		List<ErpSku> erpResSkuList = stockoutErpResourceService.findNotAmountOutErpSkuList(companyId);

		if (CollectionUtils.isNotEmpty(erpResSkuList)) {

			for (ErpSku sku : erpResSkuList) {

				// 检查单个SKU库存数量 此处需要关联大E表的companyId
				Integer amount = getRealtimeInventoryByErpSkuAmount(sku, companyId);
				if (amount != 0) {
					sku.setAmount(amount);
					/**
					 * 1.顺序出库 orderBy resid limit sku.amount
					 * 2.刷 skudetail表的 amount_out列
					 */
					quicklyComfirmResourceToErpSku(sku, companyId, ResourceStockoutLockState.LOCK);

					/**
					 * 刷 sc_e_stockout_erp_resource_sku表的 amount_out列
					 */
					stockoutErpResourceService.updateStockoutErpSkuAmountIncrementOut(sku.getEvidenceId(),
							sku.getSkuId(), amount);

					/**
					 * 写日志
					 */
					resourceLogService.stockoutResourceLoggingByErpResSku(sku.getEvidenceId(), sku.getErpResId(),
							sku.getSkuId(), ResourceLockState.UNLOCK.getValue());
				}
			}

			/**
			 * 处理可以结束的生产单
			 */
			List<String> evidenceIds = stockoutService.findCanFinishEids(companyId);
			if (CollectionUtils.isNotEmpty(evidenceIds)) {
				for (String evidenceId : evidenceIds) {

					/**
					 *1 复壮完成
					 */
					List<String> repairServiceIds = stockoutService.findStockoutRepairByEid(evidenceId);
					if (CollectionUtils.isNotEmpty(repairServiceIds)) {
						stockoutService.finishRepair(repairServiceIds);
					}

					/**
					 *2 订单完成
					 */
					stockoutService.claim(evidenceId);

					/**
					 *3 修改单子状态 
					 */
					stockoutErpResourceService.updateResQcState(evidenceId, ProductionState.QCPASS.getType());
					stockoutService.updateStockoutState(evidenceId, StockoutState.FINISH);
					outRes(evidenceId);
				}
			}

		}

	}

	protected Integer getRealtimeInventoryByErpSkuAmount(ErpSku erpSku, String companyId) {
		Integer usableAmount = resourceService.getUsableResourceBySkuId(erpSku.getSkuId(), companyId);
		if (erpSku.getAmount() <= usableAmount) {
			return erpSku.getAmount();
		} else {
			return usableAmount;
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see com.z100h.supplychain.evidence.facade.StockoutFacade#findById(java.lang.String)
	 * @author: Fyh - 1009173473@qq.com 
	 * @date: Created on 2025年7月25日 上午11:08:11
	 */
	@Override
	public Stockout findById(String id) {
		return stockoutService.findById(id);
	}

}
